package org.pewpew.client;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.TimerTask;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.pewpew.model.Command;
import org.pewpew.model.Player;

import android.util.Log;

public class HttpPoller {
	
	private static final String PEW_SERVICE = "PEW-http-poller";
	private static final int INTERVAL = 5 * 1000;
	private static final String HOSTNAME = "http://pewpew-server.appspot.com/";	
	private static final String GET_WORLD_STATE = HOSTNAME + "get-world-state?user=%s&la=%s&lo=%s&or=%s";
	private static final String SHOOT = HOSTNAME + "get-world-state?user=%s&la=%s&lo=%s&or=%s&action=shoot";
	

	private ScheduledExecutorService executor;	
	private final UICommunication comm;
	
	public HttpPoller(UICommunication comm) {
		this.comm = comm;
	}
	
	private void requestWorldData() {
		if (!comm.isReady ()) {
			Log.i (PEW_SERVICE, "System is not ready yet");
			return;
		}
		Player player = comm.getPlayer();
		String requestURL = substitutePlayer(GET_WORLD_STATE, player);
		Log.i(PEW_SERVICE, "Requesting URL: " + requestURL);	

		String response = doHttpGetRequest(requestURL);
		comm.sendWorldStateUI(response);
	}

	public void shoot(Command command) {
		if (!command.getAction().equals(Messaging.CMD_SHOOT)) {
			Log.w (PEW_SERVICE, "Command not supported: " + command.toJSON ());
		}

		if (!comm.isReady ()) {
			Log.i (PEW_SERVICE, "System is not ready yet");
			return;
		}
		
		Player player = comm.getPlayer();
		Log.i (PEW_SERVICE, "Shooting!");
		
		String requestURL = substitutePlayer(SHOOT, player);
		Log.i(PEW_SERVICE, "Requesting URL: " + requestURL);
		
		String response = doHttpGetRequest(requestURL);
		comm.sendWorldStateUI(response);
	}

	private String substitutePlayer(String url, Player player) {
		return String.format (url, 
				player.getUsername (), player.getLatitude(), 
				player.getLongitude(), player.getOrientation());
	}
	
	private String doHttpGetRequest(String requestURL) {
		HttpClient httpclient = new DefaultHttpClient();
		HttpResponse response;
		String responseString = null;
		try {
			response = httpclient.execute(new HttpGet(requestURL));
			StatusLine statusLine = response.getStatusLine();
			if (statusLine.getStatusCode() == HttpStatus.SC_OK) {
				Log.i(PEW_SERVICE, "Status OK");
				ByteArrayOutputStream out = new ByteArrayOutputStream();
				response.getEntity().writeTo(out);
				out.close();
				responseString = out.toString();
			} else {
				Log.i(PEW_SERVICE, "Closing connection");
				// Closes the connection.
				response.getEntity().getContent().close();
				throw new IOException(statusLine.getReasonPhrase());
			}
		} catch (Exception e) {
			Log.e(PEW_SERVICE, e.getMessage(), e);
		}
		Log.i(PEW_SERVICE, "Receieved from server: " + responseString);
		return responseString;
	}
	
	public void setupPollerThread() {
		executor = Executors.newSingleThreadScheduledExecutor();
		executor.scheduleAtFixedRate(new TimerTask() {
			@Override
			public void run() {
				Log.i(PEW_SERVICE, "tick");
				requestWorldData();
			}

		}, 0, INTERVAL, TimeUnit.MILLISECONDS);
	}

	public void stop() {
		executor.shutdownNow();
	}

}
